home *** CD-ROM | disk | FTP | other *** search
/ Aminet 28 / Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso / Aminet / gfx / misc / MesaGL-aux.lha / src / shapes.c < prev    next >
C/C++ Source or Header  |  1998-09-12  |  28KB  |  1,206 lines

  1. /*
  2.  * shapes.c 
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <math.h>
  8. #include "GL/gl.h"
  9. #include "GL/glu.h"
  10. #include "glaux.h"
  11. #include "3d.h"
  12.  
  13. #define SPHEREWIRE    0
  14. #define CUBEWIRE    1
  15. #define BOXWIRE        2
  16. #define TORUSWIRE    3
  17. #define CYLINDERWIRE    4
  18. #define ICOSAWIRE    5
  19. #define OCTAWIRE    6
  20. #define TETRAWIRE    7
  21. #define DODECAWIRE    8
  22. #define CONEWIRE    9
  23. #define SPHERESOLID    10
  24. #define CUBESOLID    11
  25. #define BOXSOLID    12
  26. #define TORUSSOLID    13
  27. #define CYLINDERSOLID    14
  28. #define ICOSASOLID    15
  29. #define OCTASOLID    16
  30. #define TETRASOLID    17
  31. #define DODECASOLID    18
  32. #define CONESOLID    19
  33.  
  34. #ifndef PI
  35. #define PI 3.1415926535897
  36. #endif
  37.  
  38. /*
  39.  * structure for each geometric object  
  40.  */
  41. typedef struct model {
  42.   GLuint list;                                       /*
  43.                                             * display list to render object   
  44.                                             */
  45.   struct model *ptr;                                   /*
  46.                                             * pointer to next object       
  47.                                             */
  48.   int numParam;                                       /*
  49.                                             * # of parameters              
  50.                                             */
  51.   GLdouble *params;                                   /*
  52.                                             * array with parameters        
  53.                                             */
  54. } MODEL, *MODELPTR;
  55.  
  56. /*
  57.  * array of linked lists--used to keep track of display lists 
  58.  * *    for each different type of geometric object.
  59.  */
  60. static MODELPTR lists[25] =
  61. {
  62.   NULL, NULL, NULL, NULL, NULL,
  63.   NULL, NULL, NULL, NULL, NULL,
  64.   NULL, NULL, NULL, NULL, NULL,
  65.   NULL, NULL, NULL, NULL, NULL,
  66.   NULL, NULL, NULL, NULL, NULL
  67. };
  68.  
  69. GLuint findList(int lindex, GLdouble * paramArray, int size);
  70. int compareParams(GLdouble * oneArray, GLdouble * twoArray, int size);
  71. GLuint makeModelPtr(int lindex, GLdouble * sizeArray, int count);
  72.  
  73. static void drawbox(GLdouble, GLdouble, GLdouble,
  74.             GLdouble, GLdouble, GLdouble, GLenum);
  75. static void doughnut(GLdouble, GLdouble, GLint, GLint, GLenum);
  76. static void icosahedron(GLdouble *, GLdouble, GLenum);
  77. static void octahedron(GLdouble *, GLdouble, GLenum);
  78. static void tetrahedron(GLdouble *, GLdouble, GLenum);
  79. static void subdivide(int, GLdouble *, GLdouble *, GLdouble *,
  80.               GLdouble *, GLdouble, GLenum, int);
  81. static void drawtriangle(int, int, int,
  82.              GLdouble *, GLdouble, GLenum, int);
  83. static void recorditem(GLdouble *, GLdouble *, GLdouble *,
  84.                GLdouble *, GLdouble, GLenum, int);
  85. static void initdodec(void);
  86. static void dodecahedron(GLdouble *, GLdouble, GLenum);
  87. static void pentagon(int, int, int, int, int, GLenum);
  88.  
  89. /*
  90.  * Render wire frame or solid sphere.  If no display list with
  91.  * *  the current model size exists, create a new display list.
  92.  */
  93. void auxWireSphere(GLdouble radius)
  94. {
  95.   GLUquadricObj *quadObj;
  96.   GLdouble *sizeArray;
  97.   GLuint displayList;
  98.  
  99.   sizeArray = (GLdouble *) malloc(sizeof(GLdouble) * 1);
  100.   *sizeArray = radius;
  101.   displayList = findList(SPHEREWIRE, sizeArray, 1);
  102.  
  103.   if (displayList == 0) {
  104.     glNewList(makeModelPtr(SPHEREWIRE, sizeArray, 1),
  105.           GL_COMPILE_AND_EXECUTE);
  106.     quadObj = gluNewQuadric();
  107.     gluQuadricDrawStyle(quadObj, GLU_LINE);
  108.     gluSphere(quadObj, radius, 16, 16);
  109.     glEndList();
  110.   }
  111.   else {
  112.     glCallList(displayList);
  113.     free(sizeArray);
  114.   }
  115. }
  116.  
  117. void auxSolidSphere(GLdouble radius)
  118. {
  119.   GLUquadricObj *quadObj;
  120.   GLdouble *sizeArray;
  121.   GLuint displayList;
  122.  
  123.   sizeArray = (GLdouble *) malloc(sizeof(GLdouble) * 1);
  124.   *sizeArray = radius;
  125.   displayList = findList(SPHERESOLID, sizeArray, 1);
  126.  
  127.   if (displayList == 0) {
  128.     glNewList(makeModelPtr(SPHERESOLID, sizeArray, 1),
  129.           GL_COMPILE_AND_EXECUTE);
  130.     quadObj = gluNewQuadric();
  131.     gluQuadricDrawStyle(quadObj, GLU_FILL);
  132.     gluQuadricNormals(quadObj, GLU_SMOOTH);
  133.     gluSphere(quadObj, radius, 16, 16);
  134.     glEndList();
  135.   }
  136.   else {
  137.     glCallList(displayList);
  138.     free(sizeArray);
  139.   }
  140. }
  141.  
  142. /*
  143.  * Render wire frame or solid cube.  If no display list with
  144.  * *  the current model size exists, create a new display list.
  145.  */
  146. void auxWireCube(GLdouble size)
  147. {
  148.   GLdouble *sizeArray;
  149.   GLuint displayList;
  150.  
  151.   sizeArray = (GLdouble *) malloc(sizeof(GLdouble) * 1);
  152.   *sizeArray = size;
  153.   displayList = findList(CUBEWIRE, sizeArray, 1);
  154.  
  155.   if (displayList == 0) {
  156.     glNewList(makeModelPtr(CUBEWIRE, sizeArray, 1),
  157.           GL_COMPILE_AND_EXECUTE);
  158.     drawbox(-size / 2., size / 2., -size / 2., size / 2.,
  159.         -size / 2., size / 2., GL_LINE_LOOP);
  160.     glEndList();
  161.   }
  162.   else {
  163.     glCallList(displayList);
  164.     free(sizeArray);
  165.   }
  166. }
  167.  
  168. void auxSolidCube(GLdouble size)
  169. {
  170.   GLdouble *sizeArray;
  171.   GLuint displayList;
  172.  
  173.   sizeArray = (GLdouble *) malloc(sizeof(GLdouble) * 1);
  174.   *sizeArray = size;
  175.   displayList = findList(CUBESOLID, sizeArray, 1);
  176.  
  177.   if (displayList == 0) {
  178.     glNewList(makeModelPtr(CUBESOLID, sizeArray, 1),
  179.           GL_COMPILE_AND_EXECUTE);
  180.     drawbox(-size / 2., size / 2., -size / 2., size / 2.,
  181.         -size / 2., size / 2., GL_QUADS);
  182.     glEndList();
  183.   }
  184.   else {
  185.     glCallList(displayList);
  186.     free(sizeArray);
  187.   }
  188. }
  189.  
  190. /*
  191.  * Render wire frame or solid cube.  If no display list with
  192.  * *  the current model size exists, create a new display list.
  193.  */
  194. void auxWireBox(GLdouble width, GLdouble height, GLdouble depth)
  195. {
  196.   GLdouble *sizeArray, *tmp;
  197.   GLuint displayList;
  198.  
  199.   sizeArray = (GLdouble *) malloc(sizeof(GLdouble) * 3);
  200.   tmp = sizeArray;
  201.   *tmp++ = width;
  202.   *tmp++ = height;
  203.   *tmp++ = depth;
  204.   displayList = findList(BOXWIRE, sizeArray, 3);
  205.  
  206.   if (displayList == 0) {
  207.     glNewList(makeModelPtr(BOXWIRE, sizeArray, 3),
  208.           GL_COMPILE_AND_EXECUTE);
  209.     drawbox(-width / 2., width / 2., -height / 2., height / 2.,
  210.         -depth / 2., depth / 2., GL_LINE_LOOP);
  211.     glEndList();
  212.   }
  213.   else {
  214.     glCallList(displayList);
  215.     free(sizeArray);
  216.   }
  217. }
  218.  
  219. void auxSolidBox(GLdouble width, GLdouble height, GLdouble depth)
  220. {
  221.   GLdouble *sizeArray, *tmp;
  222.   GLuint displayList;
  223.  
  224.   sizeArray = (GLdouble *) malloc(sizeof(GLdouble) * 3);
  225.   tmp = sizeArray;
  226.   *tmp++ = width;
  227.   *tmp++ = height;
  228.   *tmp++ = depth;
  229.   displayList = findList(BOXSOLID, sizeArray, 3);
  230.  
  231.   if (displayList == 0) {
  232.     glNewList(makeModelPtr(BOXSOLID, sizeArray, 3),
  233.           GL_COMPILE_AND_EXECUTE);
  234.     drawbox(-width / 2., width / 2., -height / 2., height / 2.,
  235.         -depth / 2., depth / 2., GL_QUADS);
  236.     glEndList();
  237.   }
  238.   else {
  239.     glCallList(displayList);
  240.     free(sizeArray);
  241.   }
  242. }
  243.  
  244. /*
  245.  * Render wire frame or solid tori.  If no display list with
  246.  * *  the current model size exists, create a new display list.
  247.  */
  248. void auxWireTorus(GLdouble innerRadius, GLdouble outerRadius)
  249. {
  250.   GLdouble *sizeArray, *tmp;
  251.   GLuint displayList;
  252.  
  253.   sizeArray = (GLdouble *) malloc(sizeof(GLdouble) * 2);
  254.   tmp = sizeArray;
  255.   *tmp++ = innerRadius;
  256.   *tmp++ = outerRadius;
  257.   displayList = findList(TORUSWIRE, sizeArray, 2);
  258.  
  259.   if (displayList == 0) {
  260.     glNewList(makeModelPtr(TORUSWIRE, sizeArray, 2),
  261.           GL_COMPILE_AND_EXECUTE);
  262.     doughnut(innerRadius, outerRadius, 5, 10, GL_LINE_LOOP);
  263.     glEndList();
  264.   }
  265.   else {
  266.     glCallList(displayList);
  267.     free(sizeArray);
  268.   }
  269. }
  270.  
  271. void auxSolidTorus(GLdouble innerRadius, GLdouble outerRadius)
  272. {
  273.   GLdouble *sizeArray, *tmp;
  274.   GLuint displayList;
  275.  
  276.   sizeArray = (GLdouble *) malloc(sizeof(GLdouble) * 2);
  277.   tmp = sizeArray;
  278.   *tmp++ = innerRadius;
  279.   *tmp++ = outerRadius;
  280.   displayList = findList(TORUSSOLID, sizeArray, 2);
  281.  
  282.   if (displayList == 0) {
  283.     glNewList(makeModelPtr(TORUSSOLID, sizeArray, 2),
  284.           GL_COMPILE_AND_EXECUTE);
  285.     doughnut(innerRadius, outerRadius, 8, 15, GL_QUADS);
  286.     glEndList();
  287.   }
  288.   else {
  289.     glCallList(displayList);
  290.     free(sizeArray);
  291.   }
  292. }
  293.  
  294. /*
  295.  * Render wire frame or solid cylinders.  If no display list with
  296.  * *  the current model size exists, create a new display list.
  297.  */
  298. void auxWireCylinder(GLdouble radius, GLdouble height)
  299. {
  300.   GLUquadricObj *quadObj;
  301.   GLdouble *sizeArray, *tmp;
  302.   GLuint displayList;
  303.  
  304.   sizeArray = (GLdouble *) malloc(sizeof(GLdouble) * 2);
  305.   tmp = sizeArray;
  306.   *tmp++ = radius;
  307.   *tmp++ = height;
  308.   displayList = findList(CYLINDERWIRE, sizeArray, 2);
  309.  
  310.   if (displayList == 0) {
  311.     glNewList(makeModelPtr(CYLINDERWIRE, sizeArray, 2),
  312.           GL_COMPILE_AND_EXECUTE);
  313.     glPushMatrix();
  314.     glRotatef(90.0, 1.0, 0.0, 0.0);
  315.     glTranslatef(0.0, 0.0, -1.0);
  316.     quadObj = gluNewQuadric();
  317.     gluQuadricDrawStyle(quadObj, GLU_LINE);
  318.     gluCylinder(quadObj, radius, radius, height, 12, 2);
  319.